#include <stdio.h>
#include <string.h>
#include <time.h>
#include "api.h"
#include "rand.h"
#include "bin-lwe.h"
#include "fips202.h"

#define NTESTS 10000

//test poly_mul
int test_poly_mul_speed()
{
	clock_t start,finish;
    double total_time;
	unsigned char a[DIM_N],pk[DIM_N],seed[SEED_LEN];
	unsigned char sk[DIM_N];
	int i;
	
	random_bytes(a,DIM_N);
	random_bytes(seed,SEED_LEN);
	keccak_state state;
    shake256_absorb_once(&state, seed, SEED_LEN);
	gen_e(sk,&state);
	
    start=clock();
    for(i=0;i<NTESTS;i++)
	{
		poly_mul(a,sk,pk,DIM_N);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("poly_mul time    :%f us\n",(total_time*1000000/NTESTS));
	
	return 0;
}

//test pke
int test_pke_speed()
{
	clock_t start,finish;
    double total_time;
	unsigned char pk[CRYPTO_PUBLICKEYBYTES];
	unsigned char sk[CRYPTO_SECRETKEYBYTES];
	unsigned char k1[CRYPTO_BYTES],k2[CRYPTO_BYTES],c[CRYPTO_CIPHERTEXTBYTES];
	int i;
	unsigned long long mlen=CRYPTO_BYTES,clen=CRYPTO_CIPHERTEXTBYTES;
	
	start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_encrypt_keypair(pk,sk);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("key generate time:%f us\n",(total_time*1000000/NTESTS));
	
	crypto_encrypt_keypair(pk, sk);
	random_bytes(k1, CRYPTO_BYTES);
	unsigned char seed[SEED_LEN];
	random_bytes(seed,SEED_LEN);
    start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_encrypt(c,&clen,k1,mlen,pk, seed);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("encryption time  :%f us\n",(total_time*1000000/NTESTS));
	
    start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_encrypt_open(k2,&mlen,c,clen,sk);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("decryption time  :%f us\n",(total_time*1000000/NTESTS));
    printf("\n");
	
	return 0;
}

//test kem fo
int test_kem_fo_speed()
{
	clock_t start,finish;
    double total_time;
	unsigned char pk[CRYPTO_PUBLICKEYBYTES];
	unsigned char sk[CRYPTO_SECRETKEYBYTES];
	unsigned char k1[CRYPTO_SESSION],k2[CRYPTO_SESSION],c[CRYPTO_CIPHERTEXTBYTES];
	int i;
	
	start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_kem_keypair(pk,sk);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("key generate time:%f us\n",(total_time*1000000/NTESTS));
	
	crypto_kem_keypair(pk,sk);
	random_bytes(k1, CRYPTO_SESSION);
    start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_kem_enc(c,k1,pk);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("kem_fo_enc time  :%f us\n",(total_time*1000000/NTESTS));
	
	crypto_kem_keypair(pk,sk);
	crypto_kem_enc(c,k1,pk);
    start=clock();
    for(i=0;i<NTESTS;i++)
	{
		crypto_kem_dec(k2,c,sk);
	}
    finish=clock();
    total_time=(double)(finish-start)/CLOCKS_PER_SEC;
    printf("kem_fo_dec time  :%f us\n",(total_time*1000000/NTESTS));
    printf("\n");
	
	return 0;
}